﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Apq.Collections
{
	/// <summary>
	/// 一键2值字典(映射)(典型应用:从Excel中导入指定的列到DataTable中对应的列)
	/// </summary>
	/// <typeparam name="TKey"></typeparam>
	/// <typeparam name="TValue1"></typeparam>
	/// <typeparam name="TValue2"></typeparam>
	public class Dictionary<TKey, TValue1, TValue2>
	{
		/// <summary>
		/// 映射列表
		/// </summary>
		protected List<KeyValuePair<TKey, TValue1, TValue2>> _lst = new List<KeyValuePair<TKey, TValue1, TValue2>>();

		/// <summary>
		/// 获取或设置映射
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public KeyValuePair<TKey, TValue1, TValue2> this[TKey key]
		{
			get
			{
				foreach (KeyValuePair<TKey, TValue1, TValue2> item in _lst)
				{
					if (item.Key.Equals(key))
					{
						return item;
					}
				}
				return default(KeyValuePair<TKey, TValue1, TValue2>);
			}
			set
			{
				_lst.Remove(value);
				_lst.Add(value);
			}
		}

		/// <summary>
		/// 获取Value1
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public TValue1 GetValue1(TKey key)
		{
			foreach (KeyValuePair<TKey, TValue1, TValue2> item in _lst)
			{
				if (item.Key.Equals(key))
				{
					return item.Value1;
				}
			}
			return default(TValue1);
		}

		/// <summary>
		/// 获取Value2
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public TValue2 GetValue2(TKey key)
		{
			foreach (KeyValuePair<TKey, TValue1, TValue2> item in _lst)
			{
				if (item.Key.Equals(key))
				{
					return item.Value2;
				}
			}
			return default(TValue2);
		}

		/// <summary>
		/// 设置Value1
		/// </summary>
		/// <returns></returns>
		public void SetValue1(TKey key, TValue1 value1)
		{
			int idx = IndexOf(key);
			if (idx > -1)
			{
				_lst[idx].Value1 = value1;
				return;
			}
			Add(key, value1, default(TValue2));
		}

		/// <summary>
		/// [只读]
		/// </summary>
		public List<TKey> Keys
		{
			get
			{
				List<TKey> l = new List<TKey>();
				foreach (KeyValuePair<TKey, TValue1, TValue2> item in _lst)
				{
					l.Add(item.Key);
				}
				return l;
			}
		}

		/// <summary>
		/// 设置Value2
		/// </summary>
		/// <returns></returns>
		public void SetValue2(TKey key, TValue2 value2)
		{
			int idx = IndexOf(key);
			if (idx > -1)
			{
				_lst[idx].Value2 = value2;
				return;
			}
			Add(key, default(TValue1), value2);
		}

		/// <summary>
		/// 返回指定Key在列表中的位置,-1表示不存在
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		protected int IndexOf(TKey key)
		{
			for (int i = 0; i < _lst.Count; i++)
			{
				KeyValuePair<TKey, TValue1, TValue2> item = _lst[i];
				if (item.Key.Equals(key))
				{
					return i;
				}
			}
			return -1;
		}

		/// <summary>
		/// 添加映射
		/// </summary>
		/// <param name="key"></param>
		/// <param name="value1"></param>
		/// <param name="value2"></param>
		public void Add(TKey key, TValue1 value1, TValue2 value2)
		{
			if (IndexOf(key) > -1)
			{
				throw new ArgumentException("不能添加重复的键");
			}

			KeyValuePair<TKey, TValue1, TValue2> item = new KeyValuePair<TKey, TValue1, TValue2>();
			item.Key = key;
			item.Value1 = value1;
			item.Value2 = value2;
			_lst.Add(item);
		}

		/// <summary>
		/// 清除所有映射
		/// </summary>
		public void Clear()
		{
			_lst.Clear();
		}

		/// <summary>
		/// 检测是否已包含指定Key
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public bool ContainsKey(TKey key)
		{
			return IndexOf(key) > -1;
		}

		/// <summary>
		/// 移除指定键的映射
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public void Remove(TKey key)
		{
			int idx = IndexOf(key);
			if (idx > -1)
			{
				_lst.RemoveAt(idx);
			}
		}
	}

	/// <summary>
	/// 单条 一键2值 数据
	/// </summary>
	/// <typeparam name="TKey"></typeparam>
	/// <typeparam name="TValue1"></typeparam>
	/// <typeparam name="TValue2"></typeparam>
	public class KeyValuePair<TKey, TValue1, TValue2>
	{
		public TKey Key;
		public TValue1 Value1;
		public TValue2 Value2;
	}
}
